﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Windows.Threading;

namespace TestUtilities
{
    public static class UiThread
    {
        private static Lazy<Dispatcher> _dispatcherLazy = new Lazy<Dispatcher>(Initialize,
                                                                               LazyThreadSafetyMode.
                                                                                   ExecutionAndPublication);

        private static volatile Dispatcher _dispatcher;

        [DebuggerHidden]
        public static Dispatcher Dispatcher
        {
            get { return _dispatcherLazy.Value; }
        }

        private static Dispatcher Initialize()
        {
            using (var evt = new ManualResetEventSlim(false))
            {
                var guiThread = new Thread(GuiThread);
                guiThread.TrySetApartmentState(ApartmentState.STA);
                guiThread.Name = "Test GUI Dispatcher";
                guiThread.Start(evt);

                evt.Wait();
            }

            return _dispatcher;
        }

        private static void GuiThread(object state)
        {
            _dispatcher = Dispatcher.CurrentDispatcher;

            Action action = () => ((ManualResetEventSlim) state).Set();

            _dispatcher.BeginInvoke(action, null);

            Dispatcher.Run();
        }

        public static void Cleanup()
        {
            if (_dispatcherLazy != null && _dispatcherLazy.IsValueCreated)
            {
                Dispatcher.InvokeShutdown();
                _dispatcher = null;
                _dispatcherLazy = null;
            }
        }
    }
}